package com.enba.boot.security.jwt;

import com.enba.boot.core.base.Result;
import com.enba.boot.redis.RedisOperator;
import com.enba.boot.security.enums.AuthStatusEnum;
import com.enba.boot.security.properties.SecurityJwtProperties;
import com.enba.boot.security.properties.SecurityRedisKeyProperties;
import io.jsonwebtoken.Claims;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.util.StringUtils;

/** 退出成功处理器 */
@Slf4j
public class DefaultJwtLogoutSuccessHandler implements LogoutSuccessHandler {

  private final RedisOperator redisOperator;
  private final SecurityRedisKeyProperties redisKeyProperties;
  private final JwtTokenUtils jwtTokenUtils;
  private final SecurityJwtProperties securityJwtProperties;

  public DefaultJwtLogoutSuccessHandler(
      RedisOperator redisOperator,
      SecurityRedisKeyProperties redisKeyProperties,
      JwtTokenUtils jwtTokenUtils,
      SecurityJwtProperties securityJwtProperties) {
    this.redisOperator = redisOperator;
    this.redisKeyProperties = redisKeyProperties;
    this.jwtTokenUtils = jwtTokenUtils;
    this.securityJwtProperties = securityJwtProperties;
  }

  @Override
  public void onLogoutSuccess(
      HttpServletRequest request, HttpServletResponse response, Authentication authentication)
      throws IOException, ServletException {
    String tokenHeader = request.getHeader(securityJwtProperties.getTokenHeader());
    if (StringUtils.hasText(tokenHeader)) {
      Claims claims;
      try {
        claims =
            jwtTokenUtils.parseToken(
                tokenHeader.replace(securityJwtProperties.getTokenPrefix(), ""));
      } catch (Exception e) {
        log.error("令牌非法：{}", e.getMessage(), e);
        Result.render(
            response,
            Result.err(
                AuthStatusEnum.TOKEN_ILLEGAL.getCode(), AuthStatusEnum.TOKEN_ILLEGAL.getMsg()));
        return;
      }

      String username = claims.get("userKey", String.class);

      if (redisOperator.exists(redisKeyProperties.getUserKey() + username)) {
        // 删除用户角色redis缓存
        redisOperator.delete(redisKeyProperties.getRoleKey() + username);

        // 删除用户权限redis缓存
        redisOperator.delete(redisKeyProperties.getPermissionKey() + username);

        // 删除用户基础信息redis缓存
        redisOperator.delete(redisKeyProperties.getUserKey() + username);
        Result.render(response, Result.success());
      } else {
        Result.render(
            response,
            Result.err(
                AuthStatusEnum.ACCOUNT_EXPIRED.getCode(), AuthStatusEnum.ACCOUNT_EXPIRED.getMsg()));
      }
    } else {
      Result.render(
          response,
          Result.err(
              AuthStatusEnum.AUTHENTICATION_ENTRY_POINT.getCode(),
              AuthStatusEnum.AUTHENTICATION_ENTRY_POINT.getMsg()));
    }
  }
}
